package com.huang;

import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;

import javax.crypto.Cipher;

import java.io.File;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author HuangShen
 * @Description
 * @create 2021-03-31 20:23
 */
public class RASDemo {

    public static void main(String[] args) throws Exception {
   

//             creatKeyPair("RSA",".");
        PublicKey publicKey = readPublicKey("./publicKey.pub", "RSA");
//        System.out.println(Base64.encode(publicKey.getEncoded()));
        PrivateKey privateKey = readPrivateKey("./privateKey.pri", "RSA");
//        System.out.println(Base64.encode(privateKey.getEncoded()));
        String s = encryption("测试明文", privateKey);
        System.out.println(s);
        String decrypt = decrypt(s, publicKey);
        System.out.println(decrypt);
    }


    /**
     * 私钥加密
     * @param Plaintext 加密内容
     * @param privateKey 私钥
     * @return  解密结果
     */
    public static String encryption(String Plaintext,PrivateKey privateKey){

        try {
            Cipher cipher = Cipher.getInstance("RSA");

            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] bytes = cipher.doFinal(Plaintext.getBytes());
            return Base64.encode(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 公钥解密
     * @param ciphertext 密文
     * @param publicKey 公钥
     * @return 解密结果
     */
    public static String decrypt(String ciphertext,PublicKey publicKey){
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] bytes = cipher.doFinal(Base64.decode(ciphertext.getBytes()));
            return new String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }


    /**
     * 生成公钥密钥文件
     * @param algorithm 加密算法
     * @param filePath 生成文件 存放路径
     */

    public static void creatKeyPair(String algorithm,String filePath){

        try {
            //生成密钥构造器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            //生成私钥
            PrivateKey privateKey = keyPair.getPrivate();
            //生成公钥
            PublicKey publicKey = keyPair.getPublic();
            // 获取私钥字节数组
            byte[] privateKeyEncoded = privateKey.getEncoded();
            // 获取公钥字节数组
            byte[] publicKeyEncoded = publicKey.getEncoded();
            //Base64 压缩
            String privateKeyString = Base64.encode(privateKeyEncoded);
            String publicKeyString = Base64.encode(publicKeyEncoded);
            //保存公钥私钥
            FileUtils.writeStringToFile(new File(filePath+"/publicKey.pub"),publicKeyString, StandardCharsets.UTF_8);
            FileUtils.writeStringToFile(new File(filePath+"/privateKey.pri"),privateKeyString, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取公钥
     * @param path 文件路径
     * @return PublicKey
     */
  public  static  PublicKey  readPublicKey(String  path ,String algorithm ){
      PublicKey publicKey=null;
      try {
          String publicKeyString = FileUtils.readFileToString(new File(path), StandardCharsets.UTF_8);
          KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
          X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicKeyString.getBytes()));
          publicKey= keyFactory.generatePublic(x509EncodedKeySpec);
      } catch (Exception e) {
          e.printStackTrace();
      }
      return publicKey;
  }

    /**
     * 读取私钥钥
     * @param path  文件路径
     * @return PrivateKey
     */
    public  static  PrivateKey  readPrivateKey(String  path ,String algorithm ){
        PrivateKey privateKey=null;
        try {
            String publicKeyString = FileUtils.readFileToString(new File(path),StandardCharsets.UTF_8);
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(publicKeyString));
            privateKey= keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return privateKey;
    }

}
